import {loading,success,fail} from "./loading"
//第一个参数就是模块级别的配置
export default function (config,axiosIns) {
    let {api,corsUrl=""} = config;
    let obj = {};

    //api : 模块级别的配置
    for(let key in api){
      //将公共的corsUrl 变为私有的闭包
      let corsUrlCopy = corsUrl;
      //url是必须字段  其他字段一般要赋默认值
      let {
        url,
        method="get",
        isForm=false,
        // 当前的:代表起别名
        data:configData={},
        // 当前的:代表的解构赋值中的匹配
        loading:{
          need:needLoaing=false,
          msgForSuccess="成功",
          msgForFail="失败",
          msgForLoaing="加载中..."
        }={},
        hooks:{
          beforeReq,
          afterReqSuccess,
          afterReqFail,
        }={},
        token=""
      } = api[key];  //api[key]:请求级别的配置



      // getContactList函数     : url闭包(/contactList)     corsUrl闭包:/9000
      // addContactByForm函数  :  url闭包(/contact/new/form) corsUrl闭包:/9000
      // addContactByJson函数  :  url闭包(/contact/new/json) corsUrl闭包:/9000
      // updateContact函数     :  url闭包(/contact/edit)     corsUrl闭包:/9000
      // deleteContact函数     :  url闭包(/contact)          corsUrl闭包:/9000
      //真正发请求的函数  当前函数必须返回一个promise 并且这个promise持有的值是请求的结果!
      obj[key] = async function (data,option={}) {

        let {loading:{need}={}} = option;
        //提升loadingFromWrap中need的优先级
        needLoaing = need === undefined ?needLoaing:need ;

        //将configData 和 data结合起来; data的优先级高
        data = Object.assign({},configData,data)

        //data 它有可能是一个body数据 也有可能是一个query数据
        //对data进行转化
        let transformData = "";
        if(isForm){
          //如果isForm为true 我们需要把data转化为formdata
          transformData = new FormData();
          for (let key in data){
            transformData.append(key,data[key])
          }
        }else{
          //直接使用data
          transformData = data;
        }


        //处理跨域
        if(corsUrlCopy){
          url = corsUrlCopy + url;
          corsUrlCopy=""; //让当前逻辑只执行一次!!
        }

        //携带token
        let headers = {};
        if(typeof token === "function"){
          let tokenStr = token();
          if(tokenStr){
            headers.Authorization = tokenStr;
          }
        }


        let body = "";
        try{
          //发送请求前
          beforeReq&&beforeReq.call(config)
          loading(needLoaing,msgForLoaing);
          switch (method.toLowerCase()){
            case "get":
            case "delete":
              //真正axios请求的位置
              body = await axiosIns({
                url,
                method,
                headers,
                params:transformData //作为query数据
              })
              break;
            case "post":
            case "put":
            case "patch":
              //真正axios请求的位置
              body = await axiosIns({
                url,
                method,
                headers,
                data:transformData //作为body数据
              })
              break;
          }
          //发送请求后 成功
          afterReqSuccess&&afterReqSuccess.call(config,body.data)
          success(needLoaing,msgForSuccess)
        }catch (e) {
          //发送请求后 失败
          afterReqFail&&afterReqFail.call(config,e)
          fail(needLoaing,msgForFail);
          return Promise.reject(e);
        }

        return body;
      }

    }

    return obj;
}
